<template>
  <AdVxeModal
    v-bind="$attrs"
    @register="register"
    :id="'change-password-modal'"
    :title="sendTitle"
    :close-func="handleClose"
    @ok="handleOk"
    width="30%"
  >
    <Form
      class="p-4 enter-x"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
      :model="formData"
      :rules="getFormRules"
      ref="formRef"
    >
      <FormItem
        name="OldPassword"
        class="enter-x"
        :label="t('viewmodal.changePassword.oldPassword')"
      >
        <InputPassword
          size="large"
          visibilityToggle
          v-model:value="formData.OldPassword"
          :placeholder="t('viewmodal.changePassword.oldPasswordPlaceholder')"
        >
          <template #prefix>
            <Icon icon="ri:lock-password-line" />
          </template>
        </InputPassword>
      </FormItem>
      <FormItem
        name="NewPassword"
        class="enter-x"
        :label="t('viewmodal.changePassword.newPassword')"
      >
        <StrengthMeter
          size="large"
          v-model:value="formData.NewPassword"
          :placeholder="t('viewmodal.changePassword.newPasswordPlaceholder')"
        >
          <template #prefix>
            <Icon icon="simple-icons:1password" />
          </template>
        </StrengthMeter>
      </FormItem>
      <FormItem
        name="ConfirmNewPassword"
        class="enter-x"
        :label="t('viewmodal.changePassword.confirmNewPassword')"
      >
        <InputPassword
          size="large"
          visibilityToggle
          v-model:value="formData.ConfirmNewPassword"
          :placeholder="t('viewmodal.changePassword.confirmNewPasswordPlaceholder')"
        >
          <template #prefix>
            <Icon icon="carbon-password" />
          </template>
        </InputPassword>
      </FormItem>
      <FormItem><div></div></FormItem>
    </Form>
  </AdVxeModal>
</template>
<script lang="ts" setup>
  import type { PropType } from 'vue';
  import type { Rule } from 'ant-design-vue/es/form';
  import { reactive, unref, ref } from 'vue';
  import { AdVxeModal, useModalInner } from '@/components/AdVxeModal';
  import { Form, Input } from 'ant-design-vue';
  import { RuleObject } from 'ant-design-vue/lib/form/interface';
  import { StrengthMeter } from '@/components/StrengthMeter';
  import Icon from '@/components/Icon/Icon.vue';

  import { useI18n } from '@/hooks/web/useI18n';
  import { isFunction } from '@/utils/is';
  import { propTypes } from '@/utils/propTypes';

  /** 修改密码DTO */
  export interface ChangePasswordDto {
    /** 旧密码 */
    OldPassword: string;
    /** 新密码 */
    NewPassword: string;
    /** 新密码确认 */
    ConfirmNewPassword: string;
  }

  const FormItem = Form.Item;
  const InputPassword = Input.Password;

  defineOptions({ name: 'ChangePassword' });
  const props = defineProps({
    /** 标题 */
    sendTitle: propTypes.string.def(''),
    /** 确定前回调，返回true关闭窗体 */
    beforeOkFunc: {
      type: Function as PropType<(data: ChangePasswordDto) => Promise<boolean>>,
      default: null,
    },
  });

  const { t } = useI18n();
  const formRef = ref();

  const formData: ChangePasswordDto = reactive({
    OldPassword: '',
    NewPassword: '',
    ConfirmNewPassword: '',
  });

  const [register, { closeModal, changeOkLoading }] = useModalInner(() => {
    formData.OldPassword = '';
    formData.NewPassword = '';
    formData.ConfirmNewPassword = '';
  });

  /** 获取表单规则 */
  const getFormRules: Record<string, Rule[]> = {
    OldPassword: [
      {
        required: false,
      },
    ],
    NewPassword: [
      {
        required: true,
        validator: async (_: RuleObject, value: string) => {
          if (!value) {
            return Promise.reject(t('viewmodal.changePassword.newPasswordPlaceholder'));
          }
          if (value === formData.OldPassword) {
            return Promise.reject(t('viewmodal.changePassword.pwdNotChanged'));
          }
          return Promise.resolve();
        },
        trigger: 'change',
      },
    ],
    ConfirmNewPassword: [
      {
        required: true,
        validator: async (_: RuleObject, value: string) => {
          if (!value) {
            return Promise.reject(t('viewmodal.changePassword.confirmNewPasswordPlaceholder'));
          }
          if (value !== formData.NewPassword) {
            return Promise.reject(t('viewmodal.changePassword.diffPwd'));
          }
          return Promise.resolve();
        },
        trigger: 'change',
      },
    ],
  };

  /** 验证表单 */
  const validForm = async () => {
    const form = unref(formRef);
    if (!form) return;
    const data = await form.validate();
    return data;
  };

  /** 处理确定 */
  async function handleOk() {
    const { beforeOkFunc } = props;
    const data = await validForm();
    if (!data) return;

    if (beforeOkFunc && isFunction(beforeOkFunc)) {
      changeOkLoading(true);
      try {
        const canClose = await beforeOkFunc(formData);
        if (canClose) {
          clearFormData();
          closeModal();
        }
      } finally {
        changeOkLoading(false);
      }
    } else {
      clearFormData();
      closeModal();
    }
  }

  /** 处理取消 */
  async function handleClose() {
    clearFormData();
    return true;
  }

  /** 清除表单数据 */
  function clearFormData() {
    formData.OldPassword = '';
    formData.NewPassword = '';
    formData.ConfirmNewPassword = '';
  }

  const labelCol = { span: 6 };
  const wrapperCol = { span: 16 };
</script>
